# coding:utf-8
import yaml
import os, sys, re
import argparse
import paramiko
from check_env import Hosts, get_groups, SSHConnection


class GroupVars(object):
    """ group variable object """
    def __init__(self, file):
        self.vars_file = file
        with open(self.vars_file, 'r') as f:
            self.br_vars = yaml.load(f)
        # print(self.br_vars)

    def modify_os(self, os_type):
        if self.br_vars['os'] != os_type:
            self.br_vars['os'] = os_type
            print("os already changed ,os is %s" % os_type)

    def modify_version(self, new_version):
        if new_version:
            if self.br_vars['version'] != new_version:
                print("version already changed ,version is %s" % new_version)
            for item in new_version:
                print("组件:[%s] 版本已经修改 旧版本:[%s] 新版本:[%s]" % (item, self.br_vars.get("version").get(item),new_version.get(item) ))
            for item in new_version:
                self.br_vars.get("version")[item] = new_version.get(item)

    def save(self):
        with open(self.vars_file, 'w') as f:
            yaml.dump(self.br_vars, f, default_flow_style=False)

    def printer(self):
        print(yaml.dump(self.br_vars))

def get_os_version(hosts):
    """ 获取操作系统版本 """
    os_version = set()
    pattern = re.compile(r'el[0-9]{1}')
    for item in hosts:
        if item.get('key_file'):
            client = SSHConnection(item['host'], item['port'], item['user'], item['key_file'])
        else:
            client = SSHConnection(item['host'], item['port'], item['user'], item['passwd'])
        if client.get_client():
            kernel_os = client.cmd('uname -r')
            if "SUSE" in client.cmd("cat /etc/issue |sed -n '2p'"):
                os_type = client.cmd('lsb_release  -r')
            else:
                print('OS Release Number:', kernel_os)
                os_type = pattern.findall(kernel_os)[0]
            os_version.add(os_type)
        else:
            # print("这几台服务器的操作系统版本不一致，请确保一致后重新执行！")
            return False
        client.close()
    if len(os_version) == 1:
        return os_version.pop()
    else:
        print("这几台服务器的操作系统版本不一致，请确保一致后重新执行！")
        return False


def get_new_version(is_update='no', br_vars=None, projects_args=""):
    '''
    is_update 由参数:args.update 提供, 默认是no
    br_vars 为 GroupVars(vars_file)初始化后生成的字典
    '''
    if projects_args.strip().startswith('-t'):
        projects_temp = projects_args.strip()[3:].split(',')
        projects_set = set()
        for project in projects_temp:
            projects_set.add(project.split("_")[0])
        projects = list(projects_set)
    elif projects_args == "":
        projects = br_vars.get("version")
    else:
        return None

    if is_update == "yes":
        new_dict = {}
        for item in projects:
            new_version = raw_input('请输入[%s]的新版本(默认:%s) ' % (item,br_vars.get("version").get(item))).strip()
            if new_version and  new_version.replace('.','').replace('-','').isdigit():
                new_dict[item]= new_version
            else:
                print('组件[%s]的新版号[%s]中包含非法字符或为空,将采用默认版本%s' % (item, new_version, br_vars.get("version").get(item)))
                new_dict[item] = br_vars.get("version").get(item)
        return new_dict
    else:
        return None


def printer():
    print(
        """
               AAA                PPPPPPPPPPPPPPPPP    MMMMMMMM               MMMMMMMM
              A:::A               P::::::::::::::::P   M:::::::M             M:::::::M
             A:::::A              P::::::PPPPPP:::::P  M::::::::M           M::::::::M
            A:::::::A             PP:::::P     P:::::P M:::::::::M         M:::::::::M
           A:::::::::A              P::::P     P:::::P M::::::::::M       M::::::::::M
          A:::::A:::::A             P::::P     P:::::P M:::::::::::M     M:::::::::::M
         A:::::A A:::::A            P::::PPPPPP:::::P  M:::::::M::::M   M::::M:::::::M
        A:::::A   A:::::A           P:::::::::::::PP   M::::::M M::::M M::::M M::::::M
       A:::::A     A:::::A          P::::PPPPPPPPP     M::::::M  M::::M::::M  M::::::M
      A:::::AAAAAAAAA:::::A         P::::P             M::::::M   M:::::::M   M::::::M
     A:::::::::::::::::::::A        P::::P             M::::::M    M:::::M    M::::::M
    A:::::AAAAAAAAAAAAA:::::A       P::::P             M::::::M     MMMMM     M::::::M
   A:::::A             A:::::A    PP::::::PP           M::::::M               M::::::M
  A:::::A               A:::::A   P::::::::P           M::::::M               M::::::M
 A:::::A                 A:::::A  P::::::::P           M::::::M               M::::::M
AAAAAAA                   AAAAAAA PPPPPPPPPP           MMMMMMMM               MMMMMMMM                    
        
        """)

def main(args):
    groups = get_groups(args.file)
    servers = Hosts(groups)
    servers.get_hosts()
    # hosts_list = get_hosts_list(args.file)
    os_type = get_os_version(servers.hosts)
    if not os_type:
        sys.exit(-1)
    vars_file = __file__[:__file__.rfind("/")] + "/../group_vars/all.yml"
    vars_dict = GroupVars(vars_file)
    new_version = get_new_version(is_update=args.update, br_vars=vars_dict.br_vars, projects_args=args.projects)
    vars_dict.modify_version(new_version)
    vars_dict.modify_os(os_type)
    vars_dict.save()
    printer()


if __name__ == "__main__":
    '''  '''
    base_dir = os.getcwd()
    parse = argparse.ArgumentParser()
    parse.add_argument('--file', type=str, default=base_dir+"/../hosts.ini", help='指定hosts.ini文件')
    parse.add_argument('--update', type=str, default="no", help='是否是升级')
    parse.add_argument('--projects', type=str, default="", help='升级组件名')
    args = parse.parse_args()
    main(args)
